package com.gcloud.mesh.sm;


import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.bouncycastle.util.encoders.Hex;

//https://blog.51cto.com/boytnt/2503384
public class SM2Util {
	public static Map<String,String> generateKeypair() throws Exception  {
		X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
		ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
		ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
		keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG")));
		AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair();
		 
		//私钥，16进制格式，自己保存，格式如a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853
		BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD();
		String privateKeyHex = privatekey.toString(16);
		 
		//公钥，16进制格式，发给前端，格式如04813d4d97ad31bd9d18d785f337f683233099d5abed09cb397152d50ac28cc0ba43711960e811d90453db5f5a9518d660858a8d0c57e359a8bf83427760ebcbba
		ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ();
		String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false));
		Map<String,String> keypair = new HashMap<>();
		keypair.put("private", privateKeyHex);
		keypair.put("public", publicKeyHex);
		return keypair;
	}
	public static String decoded(String cipherData, String privateKey) throws Exception {
		//String cipherData = "04be17bf6fe47da1f34a01ad0ff67901241b72d103e998f2f7cc78a004703bdfb8d2c6e3939f4f708f3a57d872d58ec5c41bbe5976666bcb01acea43f5a1c68a62cc117c24821d17c3023035641894d7c978a5521f8dc6798515550c73071f9703602e0ee490157729b648c1cc3eb929c1a0501e12a216d42461117402";
		byte[] cipherDataByte = ByteUtils.fromHexString(cipherData);
		//刚才的私钥Hex，先还原私钥
		//String privateKey = "a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853";
		BigInteger privateKeyD = new BigInteger(privateKey, 16);
		X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
		ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
		ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
		 
		//用私钥解密
		SM2Engine sm2Engine = new SM2Engine();
		sm2Engine.init(false, privateKeyParameters);
		 
		//processBlock得到Base64格式，记得解码
		byte[] ci = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
		String data = ByteUtils.toHexString(ci);
//		byte[] arrayOfBytes = Base64.getDecoder().decode(ci);
//		 
//		//得到明文：SM2 Encryption Test
//		String data = new String(arrayOfBytes);
		return  data;
	}
//	public static void main(String[] args) throws Exception {
////		Map<String,String> keypair = generateKeypair();
////		String privateKey = keypair.get("private");
////		String publicKey = keypair.get("public");
////		System.out.println("私钥是："+privateKey+"\n");
////		System.out.println("公钥是："+publicKey+"\n");
////		String src = SM2Util.decoded("763AFC537F7876C2D0B59FDB68D762E90CEFD222BB358D0D6931867CE26538649BE3579A4004483EA5D84D005063F76FB1CE7E5F2F933B5ED757A718182F383C4D58291A6A5D8D07C081F66806031539093362D854883A8874F7B919925DABC74C173E2162F07E6780E311FF0AEF059AE620303DECB6289E97F72C018723C471", "E7CB09606A53320B347F61F3F142DCB118F723A9BC27879F2805BE778F24AEE5");
//		String privateKey = "a2081b5b81fbea0b6b973a3ab6dbbbc65b1164488bf22d8ae2ff0b8260f64853";
//		//privateKey = "E7CB09606A53320B347F61F3F142DCB118F723A9BC27879F2805BE778F24AEE5";
//		BigInteger privateKeyD = new BigInteger(privateKey, 16);
//		X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
//		ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN());
//		ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
//		//		System.out.println(src);
//		String cipherData = "04be17bf6fe47da1f34a01ad0ff67901241b72d103e998f2f7cc78a004703bdfb8d2c6e3939f4f708f3a57d872d58ec5c41bbe5976666bcb01acea43f5a1c68a62cc117c24821d17c3023035641894d7c978a5521f8dc6798515550c73071f9703602e0ee490157729b648c1cc3eb929c1a0501e12a216d42461117402";
//		//cipherData = "9E2A4A1AA4CF772622ABBBF1C6D661EE58FF01FF9843782E5A63185ABF6C2EFA9B2D59B2B1E0D0A795BFEF53FABB24C03A02265751B820591200F0D31C551ED67DFDFC65CC9DF7D6287D5BF3358BED992881B69FBA13C8AF76EFC157455DB81ECFACC7B443EA1DB0";
//		byte[] cipherDataByte = Hex.decode(cipherData);
//
//		//刚才的私钥Hex，先还原私钥
//		//用私钥解密
//		SM2Engine sm2Engine = new SM2Engine();
//		sm2Engine.init(false, privateKeyParameters);
//
//		//processBlock得到Base64格式，记得解码
//		byte[] arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
//
//		//得到明文：SM2 Encryption Test
//		String data = new String(arrayOfBytes);
//		System.out.println(data);
//		
//	}
}
